
package controllers.playerControlers;

import game.Game;

import java.util.*;

import classes.cards.CityCard;
import classes.cards.IPlayerCard;
import classes.cards.PlayerCityCard;
import classes.city.City;
import classes.diseases.Disease;
import classes.players.Player;

public class ActionsVerifier {

	private static boolean canDrive;
	private static boolean canDirectFlight;
	private static boolean canCharterFlight;
	private static boolean canShuttleFlight;
	private static boolean canBuildReserachStation;
	private static boolean canTreatDisease;
	private static boolean canDiscoverACure;
	private static boolean canRecieveKnowledge;
	private static boolean canShareKnowledge;
	private static HashSet<String> list;

	public static void verifyAllActions(Player player) {
		canDrive = canDrive(player);
		canDirectFlight = canDirectFlight(player);
		canCharterFlight = canCharterFlight(player);
		canShuttleFlight = canShareKnowledge(player);
		canBuildReserachStation = canBuildReserachStation(player);
		canTreatDisease = canTreatDisease(player);
		canDiscoverACure = canDiscoverACure(player);
		canRecieveKnowledge = canRecieveKnowledge(player);
		canShareKnowledge = canShareKnowledge(player);
	}

	public static boolean getCanDrive() {
		return canDrive;
	}

	public static boolean getCanDirectFlight() {
		return canDirectFlight;
	}

	public static boolean getCanCharterFlight() {
		return canCharterFlight;
	}

	public static boolean getCanShuttleFlight() {
		return canShuttleFlight;
	}

	public static boolean getCanBuildReserachStation() {
		return canBuildReserachStation;
	}

	public static boolean getCanTreatDisease() {
		return canTreatDisease;
	}

	public static boolean getCanDiscoverACure() {
		return canDiscoverACure;
	}

	public static boolean getCanRecieveKnowledge() {
		return canRecieveKnowledge;
	}

	public static boolean getCanShareKnowledge() {
		return canShareKnowledge;
	}

	public static boolean canDrive(Player player) {
		return true;
	}

	public static HashSet<City> getDriveOpitions(Player player) {
		// TODO return connected cities
		return null;
	}

	private static boolean canDirectFlight(Player player) {

		if (!player.getHand().isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	public static HashSet<String> getDirectFlightOptions(Player player) {
		return getPlayerCityCards(player);
	}

	public static boolean canCharterFlight(Player player) {
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				if (((CityCard) card).getCity().equals(player.getLocation())) {
					return true;
				}
			}
		}
		return false;
	}

	public static HashSet<String> getCharterFlightOptions(Player player) {
		list = new HashSet<String>();
		list.addAll(Game.getInstance().getCities().keySet());
		list.remove(player.getLocation().getName());
		return list;
	}

	public static boolean shuttleFlight(Player player) {
		if (player.getLocation().getHasResearchCentre()) {
			for (City city : Game.getInstance().getCities().values()) {
				if ((!city.equals(player.getLocation()))
						&& city.getHasResearchCentre()) {
					return true;
				}
			}
		}
		return false;
	}

	public static HashSet<String> getShuttleFlightOptions(Player player) {
		list = new HashSet<String>();
		for (City city : Game.getInstance().getCities().values()) {
			if (city.getHasResearchCentre()
					&& !city.equals(player.getLocation())) {
				list.add(city.getName());
			}
		}
		return list;
	}

	public static boolean canBuildReserachStation(Player player) {
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				if (((CityCard) card).getCity().equals(player.getLocation())) {
					return true;
				}
			}
		}
		return false;
	}

	public static boolean canTreatDisease(Player player) {
		if (player.getLocation().getInfectionLevel() > 0) {
			return true;
		} else {
			return false;
		}
	}

	public static boolean canDiscoverACure(Player player) {
		if (player.getLocation().getHasResearchCentre()) {
			if (!getDiscoverACureOptions(player).isEmpty()) {
				return true;
			}
		}
		return false;
	}

	public static HashSet<String> getDiscoverACureOptions(Player player) {
		list = new HashSet<String>();
		for (Disease disease : Game.getInstance().getDiseases().values()) {
			int count = 0;
			for (IPlayerCard card : player.getHand().values()) {
				if (card instanceof CityCard) {
					if (((CityCard) card).getDisease().equals(disease)) {
						count++;
					}
				}
			}
			if (count >= 5) {
				list.add(disease.getName());
			}
		}
		return list;
	}

	public static boolean canRecieveKnowledge(Player player) {
		if (getRecieveKnowledgeOptions(player).isEmpty()) {
			return true;
		}
		return false;
	}

	public static HashSet<String> getRecieveKnowledgeOptions(Player player) {
		list = new HashSet<String>();
		for (Player otherPlayer : Game.getInstance().getPlayers().values()) {
			if (!player.equals(otherPlayer)
					&& player.getLocation().equals(otherPlayer.getLocation())
					&& otherPlayer.getHand().isEmpty()) {
				list.add(otherPlayer.getUsername());
			}
		}
		return list;
	}

	public static boolean canShareKnowledge(Player player) {
		if (canRecieveKnowledge(player) && !player.getHand().isEmpty()) {
			return true;
		}
		return false;
	}

	public static HashSet<String> getShareKnowledgeOptions(Player player) {
		list = new HashSet<String>();
		for (Player otherPlayer : Game.getInstance().getPlayers().values()) {
			if (!player.equals(otherPlayer)
					&& player.getLocation().equals(otherPlayer.getLocation())) {
				list.add(otherPlayer.getUsername());
			}
		}
		return list;
	}
	
	public static HashSet<String> getPlayerCityCards (Player player) {
		list = new HashSet<String>();
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				list.add(((CityCard) card).getCity().getName());
			}
		}
		list.remove(player.getLocation().getName());
		return list;
	}
}
